package nb.photoviewer.ImageEditor;

import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.Cursor;
import javafx.scene.Scene;
import javafx.scene.SnapshotParameters;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.Button;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.Slider;
import javafx.scene.effect.ColorAdjust;
import javafx.scene.image.*;

import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URL;
import java.nio.ByteBuffer;
import java.util.ResourceBundle;
import javafx.scene.effect.BoxBlur;
import javafx.scene.image.Image;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Polygon;
import javafx.scene.shape.Rectangle;
import javafx.stage.FileChooser;
import javax.imageio.ImageIO;

import javafx.embed.swing.SwingFXUtils;
import javafx.stage.Stage;


public class EditorController implements Initializable {
    private File editImage;   //编辑的图片对象
    private Image cropImage;    //裁剪后的Image
    private EditorManager editorManager;

    @FXML
    private ImageView imageView;    //放置图片

    @FXML
    private Button saveButton;    //保存按钮
    @FXML
    private Button reductionButton;   //还原按钮
    @FXML
    private Button amplifyButton;  //放大按钮
    @FXML
    private Button reduceButton;   //缩小按钮
    @FXML
    private Button cutButton;     //裁剪按钮

    @FXML
    private ScrollPane scrollPane;   //左边目录栏滚轮板，放置调节参数的东西
    @FXML
    private StackPane stackPane;      //保存imageView的pane
    @FXML
    private Slider brightnessSlider;    //亮度滑动条
    @FXML
    private Slider colortemperatureSlider;    //色温滑动条
    @FXML
    private Slider grayscaleSlider;      //灰度滑动条
    @FXML
    private Slider contrastSlider;    //对比度滑动条


    // 定义全局的ColorAdjust对象，用于调节颜色
    private ColorAdjust colorAdjust = new ColorAdjust();  //对图片进行调节之后使用组合效果，确保每次调整属性时，不会重置其他属性。

    //scrollerpane实现左右拖动
    private double xOffset = 0;
    private double yOffset = 0;

    public void initialize(URL url, ResourceBundle resourceBundle){//注意此时图片还没有传过来，editImage还不可以用
        //给按钮加图标
        // 创建图标
        FileInputStream input3=null,input4=null;
        FileInputStream input5=null,input6=null ,input7=null,input8=null;;
        try {
            input3= new FileInputStream("src/main/resources/nb/photoviewer/img/放大按钮.png");
            input4 = new FileInputStream("src/main/resources/nb/photoviewer/img/缩小按钮.png");
            input5= new FileInputStream("src/main/resources/nb/photoviewer/img/保存.png");
            input6 = new FileInputStream("src/main/resources/nb/photoviewer/img/数据还原.png");
            input7= new FileInputStream("src/main/resources/nb/photoviewer/img/图片裁剪.png");
            initializeButton(input3,amplifyButton);
            initializeButton(input4,reduceButton);
            initializeButton(input5,saveButton);
            initializeButton(input6,reductionButton);
            initializeButton(input7,cutButton);
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }

        System.out.println("controller    imageview   "+imageView);
        System.out.println("EditorController initailize  先");
        editorManager=new EditorManager(imageView);
        System.out.println("EditorController initailize  后");

        // 添加鼠标悬停事件监听器，当鼠标停留在imageview上时切换为手形
        imageView.setOnMouseEntered(event -> {
            imageView.setCursor(Cursor.HAND); // 鼠标悬停时改变鼠标图标为手型
        });
        imageView.setOnMouseExited(event -> {
            imageView.setCursor(Cursor.DEFAULT); // 鼠标离开时恢复默认图标
        });

        // 添加滚轮事件监听器
        imageView.setOnScroll(event -> {
            double deltaY = event.getDeltaY(); // 获取滚轮滚动的垂直距离
            // 根据滚动方向调整图片大小
            if (deltaY < 0) {
                reduceImage();
            } else {
                amplifyImage();
            }
            event.consume(); // 防止滚动事件继续传播
        });

        //设置scrollerpane拖动还有隐藏滑轮
        initializeScrollerPane(scrollPane);

        //监听亮度滑动条数值变化
        brightnessSlider.valueProperty().addListener((observable, oldValue, newValue) -> {
            adjustBrightness(); // 调整亮度
        });
        // 监听色温滑动条数值变化
        colortemperatureSlider.valueProperty().addListener((observable, oldValue, newValue) -> {
            adjustColorTemperature(newValue.doubleValue()); // 调整色温
        });
        // 监听灰度滑动条数值变化
        grayscaleSlider.valueProperty().addListener((observable, oldValue, newValue) -> {
            //adjustGrayscale(newValue.doubleValue()); // 调整灰度
            adjustGrayscale();
        });
        // 监听对比度滑动条数值变化
        contrastSlider.valueProperty().addListener((observable, oldValue, newValue) -> {
            adjustContrast(); // 调整对比度
        });

        //滑动条美化
        // 应用自定义样式
        initializeSlider(brightnessSlider);
        initializeSlider(colortemperatureSlider);
        initializeSlider(grayscaleSlider);
        initializeSlider(contrastSlider);

//裁剪按钮
        cutButton.setOnAction(e -> {
            cropImage=null;//初始化
            // 创建新的窗口————手搓一个布局出来
            Stage cropStage = new Stage();
            // 设置窗口不能改变大小和最大化
            cropStage.setResizable(false);
            cropStage.setMaximized(false);
            // 设置图标

            Image cropperIcon = new Image("file:src/main/resources/nb/photoviewer/img/截图.png");
            cropStage.getIcons().add(cropperIcon);




            // 创建Cropper实例并传入图片,注意，Cropper是一个BorderPane
            Cropper cropper = new Cropper(new Image(editImage.toURI().toString()));
            // 创建完成裁剪按钮
            Button finishButton = new Button("完成裁剪");
            finishButton.setOnAction(event -> {
                // 执行裁剪操作
                cropImage=cropper.performCrop();
                if(cropImage!=null) {
                    imageView.setImage(cropImage);
                }
                //关闭裁剪窗口
                cropStage.close();
            });
            // 创建布局并添加控件
            Button cancelButton = new Button("取消");
            cancelButton.setOnAction(event -> {
                //关闭裁剪窗口
                cropStage.close();
            });
            HBox buttonsBox = new HBox(30, cancelButton,finishButton);
            buttonsBox.setStyle("-fx-padding: 10px; -fx-alignment: center;");
            cropper.setBottom(buttonsBox);

            // 设置场景并显示窗口
            cropStage.setScene(new Scene(cropper));

            cropStage.show();
        });
//裁剪按钮

    }

    private void initializeButton(FileInputStream input,Button button){
        ImageView icon=new ImageView(new Image(input));
        icon.setFitWidth(35);
        icon.setFitHeight(35);
        button.setGraphic(icon);
    }
    private void initializeSlider(Slider slider){
        // 应用自定义样式
        slider.setStyle("-fx-control-inner-background: #d3d3d3; " +
                "-fx-background-color: #ffffff, #ffffff, linear-gradient(#444444 0%, #000000 100%);" +
                "-fx-background-insets: 0 0 -1 0, 0, 1, 2; " +
                "-fx-background-radius: 5em; " +
                "-fx-padding: 0.333333em 0.666667em 0.333333em 0.666667em; " +
                "-fx-text-fill: #d3d3d3; " +
                "-fx-slider-handle-color: #ffffff; " +
                "-fx-slider-handle-stroke: #000000; " +
                "-fx-slider-handle-highlight: #444444; " +
                "-fx-slider-track-color: #202020; " +
                "-fx-slider-track-stroke: #000000;" );


    }
    public void setEditImage(File editImage){
         this.editImage=editImage;//ok图片传到controller来了
         System.out.println("editorcontroller"+editImage.getName());
         editorManager.SetImage(this.editImage);

    }

    @FXML
    private void amplifyImage() {    //放大功能
        imageView.setScaleX(imageView.getScaleX() * 1.2);
        imageView.setScaleY(imageView.getScaleY() * 1.2);
    }
    @FXML
    private void reduceImage() {   //缩小功能
        imageView.setScaleX(imageView.getScaleX() / 1.2);
        imageView.setScaleY(imageView.getScaleY() / 1.2);
    }

    @FXML//还原图片
    private void reductionImageView(){
        editorManager.SetImageView();
        brightnessSlider.setValue(0.0);
        colortemperatureSlider.setValue(0.0);
        grayscaleSlider.setValue(0.0);
        contrastSlider.setValue(0.0);
    }

    private void initializeScrollerPane(ScrollPane scrollpane){
        scrollpane.setCenterShape(true);
        // 设置水平滚动条始终显示，垂直滚动条不显示
        scrollpane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
        scrollpane.setVbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
        // 鼠标按下记录偏移量
        scrollpane.setOnMousePressed(event -> {
            xOffset = event.getSceneX();
            yOffset = event.getSceneY();
            scrollpane.setPannable(true);
        });
        // 鼠标拖动时更新滚动位置
        scrollpane.setOnMouseDragged(event -> {
            scrollpane.setHvalue(scrollpane.getHvalue() - (event.getSceneX() - xOffset) / scrollpane.getWidth());
            scrollpane.setVvalue(scrollpane.getVvalue() - (event.getSceneY() - yOffset) / scrollpane.getHeight());
        });
        // 鼠标释放停止拖动
        scrollpane.setOnMouseReleased(event -> {
            scrollpane.setPannable(false);
        });
    }


    @FXML
    private void adjustBrightness() {
        double brightnessValue = brightnessSlider.getValue(); // 获取滑动条的值
        colorAdjust.setBrightness(brightnessValue); // 将滑动条值直接应用到亮度调整
        imageView.setEffect(colorAdjust); // 将颜色调整应用到图片上
    }
    @FXML
    private void adjustColorTemperature(double temperatureValue) {
        // 根据色温值调整色温
        double hue = temperatureValue * 0.1; // 根据滑动条值计算对应的 hue 值
        colorAdjust.setHue(hue);
        imageView.setEffect(colorAdjust); // 将颜色调整应用到图片上
    }
    @FXML
    private void adjustGrayscale() {
        double grayscaleValue = grayscaleSlider.getValue(); // 获取滑动条的值
        colorAdjust.setSaturation(-grayscaleValue); // 设置饱和度（负值表示转为灰度）
        imageView.setEffect(colorAdjust); // 将颜色调整应用到图片上
    }
    @FXML
    private void adjustContrast() {
        double contrastValue = contrastSlider.getValue(); // 获取滑动条的值
        colorAdjust.setContrast(contrastValue); // 设置对比度
        imageView.setEffect(colorAdjust); // 将颜色调整应用到图片上
    }

    @FXML
    private void saveImage() throws FileNotFoundException {
        // 创建 WritableImage 对象以存储 imageView 中的图像
        WritableImage writableImage = new WritableImage((int) imageView.getImage().getWidth(), (int) imageView.getImage().getHeight());
        imageView.snapshot(null, writableImage); // 将 imageView 中的图像快照存储到 writableImage 中
        // 获取原始图像的输入流
        InputStream inputStream = new FileInputStream(editImage.getPath());
        Image image = new Image(inputStream);
        // 获取原始图像的文件格式
       // String[] formatExtensions = ImageIO.getWriterFileSuffixes();
        String defaultFormat = "png"; // 默认格式为 PNG
       /* for (String extension : formatExtensions) {
            if (editImage.getName().toLowerCase().endsWith(extension)) {
                defaultFormat = extension;
                break;
            }
        }*/
        // 创建文件选择器来选择保存位置
        FileChooser fileChooser = new FileChooser();
        fileChooser.setTitle("Save Image");
        // 设置文件过滤器以限制保存类型，也就是保存时的提示信息
        FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter("Image files (*." + defaultFormat + ")", "*." + defaultFormat);
        fileChooser.getExtensionFilters().add(extFilter);
        // 显示文件保存对话框并获取用户选择的文件
        File file = fileChooser.showSaveDialog(imageView.getScene().getWindow());
        System.out.println("file   "+file);
        System.out.println("defaultFormat    "+defaultFormat);
        if (file != null) {
            try {
                // 将 WritableImage 转换为 BufferedImage
                BufferedImage bImage = SwingFXUtils.fromFXImage(writableImage, null);
                // 尝试保存图像
                if (ImageIO.write(bImage, defaultFormat, file)) {
                    System.out.println("Image saved successfully."+file);
                } else {
                    System.out.println("Failed to save image.");
                }

            } catch (IOException ex) {
                System.out.println("Error saving image: " + ex.getMessage());
                ex.printStackTrace();
            }
        }
    }

}
